/*******************************************************************************
 * Copyright（C） CETC-32
 * @file:JWTUtil.java
 * @Description：
 * @Author ：徐文远
 * @version：1.0
 * @date ： 2021/2/2 下午1:58
 ******************************************************************************/

package com.cetc32.webutil.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {
    //token有效时长
    private static final long  EXPIRE=2*60*60*1000;
    //token的密钥
    private static final String SECRET="jwt#CETC@32s%&";
    private static Logger logger = LoggerFactory.getLogger(JWTUtil.class);
    /**
     * 生成有效期2小时的token
     * @param username 用户名
     * @param current 时间(秒)
     * @return
     * 修改信息：
     */
    public  static String createToken(String username,long current){
        return createToken(username,current,EXPIRE);
    }
    /**
     * 生成指定有效期市场的token
     * @param username 用户名
     * @param current 时间(毫秒)
     * @param expire 有效期(毫秒)
     * @return
     * 修改信息：
     */
    public  static String createToken(String username,long current,long expire){
        if(expire<0){
            return createToken(username);
        }
        Date date= new Date(current+expire);
        //JWT的header部分
        Map<String ,Object> map =new HashMap<>();
        map.put("alg","HS256");
        map.put("typ","JWT");

        //使用JWT生成 token
        String token=null;
        try{
            token= JWT.create()
                    .withHeader(map)
                    .withClaim("username",username)
                    .withClaim("current",current)
                    .withIssuedAt(new Date())
                    .withExpiresAt(date)
                    .sign(Algorithm.HMAC256(SECRET));
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return token;
    }
    /**
     * 生成指定有效期市场的token
     * @param username 用户名
     * @return
     * 修改信息：
     */
    public  static String createToken(String username){
        //Date date= new Date(current);
        //JWT的header部分
        Map<String ,Object> map =new HashMap<>();
        map.put("alg","HS256");
        map.put("typ","JWT");

        //使用JWT生成 token
        String token=null;
        try{
            token= JWT.create()
                    .withHeader(map)
                    .withClaim("username",username)
                    //.withClaim("current",current)
                    //.withIssuedAt(new Date())
                    .withExpiresAt(null)
                    .sign(Algorithm.HMAC256(SECRET));
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return token;
    }
    ////校验token的有效性，1、token的header和payload是否没改过；2、没有过期
    /**
     * 指定缓存失效时间
     * @param token 键
     * @return
     * 修改信息：
     */
    public static boolean verify(String token){
        try{
            JWTVerifier verifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            verifier.verify(token);
            return true;
        }catch ( Exception e){

        }
        return false;
    }
    //无需解密也可以获取token的信息
    /**
     * 指定缓存失效时间
     * @param token 键
     * @return
     * 修改信息：
     */
    public static String getUsername(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    //获取过期时间
    /**
     * 指定缓存失效时间
     * @param token 键
     * @return
     * 修改信息：
     */
    public static long getExpire(String token){
        try {
            if(StringUtils.isBlank(token))
                return -1L;
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("exp").asLong();
        }catch (NullPointerException e){
            //e.printStackTrace();
            logger.debug("token getExpire NullPointerException ,will Return never expired time");
            return (new Date()).getTime()/1000+ 7200000L;
        }catch (NumberFormatException e){
            //e.printStackTrace();
            logger.debug("token getExpire NumberFormatException ,will Return current time");
            return -1L;
        }catch (Exception e){
            logger.debug("token getExpire Exception ,will Return current time");
            return -1L;
        }
    }
}

